import java.util.Comparator;
import java.util.Objects;
import java.util.PriorityQueue;
import java.util.Queue;

//对象的比较:1.重写equals方法比较对象
         //2.通过实现Comparable接口，调用compareTo方法，来比较
         //3.自定义一个实现了Comparator接口的类（比较器），通过重写compare方法，比较两个对象

class Student implements Comparable<Student>{
    public int age;
    public String name;
    public Student(String name,int age) {
        this.name=name;
        this.age=age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age && Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(age, name);
    }

    @Override
    public int compareTo(Student o) {
        return this.age-o.age;         //这样写默认是小根堆，反过来写就是大根堆
    }
}
//设置不同的比较器
class NameComparator implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.name.compareTo(o2.name);
    }
}
class AgeComparator implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return o2.age-o1.age;
    }
}
class Incmp implements Comparator<Integer>{            //要让Integer通过这个比较器实现大堆，就要将compare方法，使用Integer来比较

    @Override
    public int compare(Integer o1, Integer o2) {
        return o2.compareTo(o1);                        //这样写就是大根堆
    }
}
public class ObjectCompare {
    public static void main(String[] args) {
        Queue<Student> priorityQueue=new PriorityQueue<>();             //不传入参数会默认判别传入的参数是否实现了Comparable接口，如果没有就会报类型转换的错误
        Student student1 = new Student("詹三", 18);           //如果传入的参数类型实现了Comparable接口，那么就会根据compareTo方法，判断是按照大/小根堆
        Student student2 = new Student("王五", 15);          //的方式插入或删除元素
        //NameComparator nameComparator = new NameComparator();

        //对象的比较:1.通过一个实现了Comparable接口的类的compareTo方法，实现小根堆/大根堆，2.如果已经写死如Integer,就可以传入一个比较器
                 //3.可以将比较器的对象参入构造方法
        priorityQueue.offer(student1);
        priorityQueue.offer(student2);

        AgeComparator ageComparator = new AgeComparator();
        Queue<Student> priorityQueue1=new PriorityQueue<>(ageComparator);    //可以传入实现了Comparator接口的引用
        priorityQueue1.offer(student1);
        priorityQueue1.offer(student2);

        Incmp incmp=new Incmp();
        Queue<Integer> priorityQueue2=new PriorityQueue<>(incmp);    //像Integer这种compareTo方法已经写死了表示小根堆，要想实现大根堆，就要传比较器
        priorityQueue2.offer(1);
        priorityQueue2.offer(2);
        //等价的写法
        Queue<Integer> priorityQueue3=new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2.compareTo(o1);                          //匿名内部类
            }
        });
    }

    public Integer x=10;
    public Comparable<Integer> comparator=(Comparable<Integer>)x;   //如果要这样强转说明x是实现了Comparable这个接口的，就是默认这个地方是可以比较的
    //public Comparable<Integer> comparator=(Comparable<Integer>)Student.name;
}
